package com.seeyon.apps.kk.manager;

import java.io.File;
import java.text.DateFormat;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.druid.util.StringUtils;
import com.kg.commons.utils.CollectionUtils;
import com.seeyon.apps.kk.manager.datasync.AbstractDataSyncManager;
import com.seeyon.apps.kk.vo.FilePathVo;
import com.seeyon.ctp.common.cache.CacheMap;
import com.seeyon.ctp.common.constants.ApplicationCategoryEnum;
import com.seeyon.ctp.common.filemanager.Constants.ATTACHMENT_TYPE;
import com.seeyon.ctp.common.filemanager.dao.AttachmentDAO;
import com.seeyon.ctp.common.filemanager.manager.FileManager;
import com.seeyon.ctp.common.filemanager.manager.FileSecurityManager;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.common.po.filemanager.V3XFile;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.services.FileUploadExporter;
import com.seeyon.ctp.util.UUIDLong;

import com.seeyon.ctp.common.cache.CacheAccessable;
import com.seeyon.ctp.common.cache.CacheFactory;
import com.seeyon.ctp.common.cache.cluster.CacheNotification;
import com.seeyon.ctp.common.customize.manager.CustomizeManager;
import com.seeyon.ctp.common.po.customize.CtpCustomize;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import jersey.repackaged.com.google.common.collect.Maps;

/**
 * 个人头像自动更改
 * 
 * @author Administrator
 *
 */
public class KKMemberHeadImageManagerImpl extends AbstractDataSyncManager {

	private final Log log = LogFactory.getLog(KKMemberHeadImageManagerImpl.class);

	private AttachmentDAO attachmentDAO;
	private FileManager fileManager;
	private OrgManager orgManager;
	private CustomizeCache cache = new CustomizeCache();
	
	private FileSecurityManager fileSecurityManager;
	public FileSecurityManager getFileSecurityManager() {
		return fileSecurityManager;
	}

	public void setFileSecurityManager(FileSecurityManager fileSecurityManager) {
		this.fileSecurityManager = fileSecurityManager;
	}

	/**
	 * 定义个人图标 key
	 */
	private static final String AVATAR_KEY = "avatar";

	/**
	 * 个人图标存放路径
	 */
	private static final String filepath = "/OAFiles/A8/Empfiles/photo";

	public AttachmentDAO getAttachmentDAO() {
		return attachmentDAO;
	}

	public void setAttachmentDAO(AttachmentDAO attachmentDAO) {
		this.attachmentDAO = attachmentDAO;
	}

	public FileManager getFileManager() {
		return fileManager;
	}

	public void setFileManager(FileManager fileManager) {
		this.fileManager = fileManager;
	}

	public OrgManager getOrgManager() {
		return orgManager;
	}

	public void setOrgManager(OrgManager orgManager) {
		this.orgManager = orgManager;
	}

	/**
	 * 获取缓存对象
	 * 
	 * @param memberId
	 * @return
	 */
	public CtpCustomize getCustomizeInfo(Long memberId, String key) {
		return this.cache.get(memberId, key);
	}

	/**
	 * 执行文件上传 返回fileID createDate
	 */
	public Attachment fileUploadMemberHeadImage(String fileName) {
		try {
			FileUploadExporter uploadExporter = new FileUploadExporter();
			String processUploadStr = uploadExporter.processUpload("admin2",
					new String[] { filepath + "/" + fileName });
			V3XFile vfile = fileManager.getV3XFile(Long.valueOf(processUploadStr));
			Attachment att = new Attachment(vfile, ApplicationCategoryEnum.collaboration, ATTACHMENT_TYPE.IMAGE);
			att.setSubReference(UUIDLong.longUUID());
			att.setCategory(1);
			att.setIdIfNew();
			attachmentDAO.save(att);
			return att;
		} catch (Exception e) {
			log.info("========shkk 修改头像错误======" + e.getMessage());
			return null;
		}
	}
	
	  private void writePersonalPhotoToFileSecurity(List<CtpCustomize> customizeList)
	    {
	    	String customizePhoteKey="avatar";
	    	for(CtpCustomize custiomize:customizeList)
	    	{
	    		String ckey=custiomize.getCkey();
	    		if(customizePhoteKey.equals(ckey.trim().toLowerCase()))
	    		{
	    		   	//对保存的图片值进行解析，形如：fileId=-4852049577399139232&createDate=2016-04-20
	    			String cvalue=custiomize.getCvalue();
	    			if(cvalue!=null)
	    			{
	    				//添加不为null的防护处理,支艳强，2016/10/12
	    				String[] cvalueArray=cvalue.split("&");
	        		   	if(cvalueArray.length>0)
	        		   	{
	        		   		String fileIdStrAll=cvalueArray[0];
	        		   		String[] fileIdStrArray=fileIdStrAll.split("=");
	        		   		if(fileIdStrArray.length>1)
	        		   		{
	        		   			String fileIdStr=fileIdStrArray[1];
	        		   			log.debug("个性化图像信息添加到白名单中:" + fileIdStr);
	        		   			fileSecurityManager.addNeedlessLogin(fileIdStr);
	        		   		}
	        		   		
	        		   	}
	    			}
	    	    }
	    	}
	    }

	/**
	 * 执行修改操作 params fileID createDate
	 */
	public Map<String, String> updateMenberHeadImage() {
		Map<String, String> rMap = Maps.newHashMap();
		try {
			String selectMemberSql = "SELECT ORG_MEMBER.ID, ORG_MEMBER.CODE,CTP_ATTACHMENT.FILENAME FROM ORG_MEMBER LEFT JOIN CTP_CUSTOMIZE ON CTP_CUSTOMIZE.USER_ID = ORG_MEMBER.ID LEFT JOIN CTP_ATTACHMENT ON TO_CHAR(CTP_ATTACHMENT.FILE_URL) = SUBSTR(TO_CHAR(CTP_CUSTOMIZE.CVALUE), 8, 20) WHERE ORG_MEMBER.IS_DELETED = 0 AND ORG_MEMBER.IS_ENABLE = 1 AND ORG_MEMBER.CODE IS NOT NULL AND CTP_CUSTOMIZE.CKEY = 'avatar'";
			List<Map<String, Object>> selectMemberList = this.jdbcTemplate.queryForList(selectMemberSql);
			Map<String, FilePathVo> imageMap = readfile();
			for (Map<String, Object> memberMap : selectMemberList) {
				FilePathVo filePathVo = (FilePathVo) MapUtils.getObject(imageMap,
						MapUtils.getString(memberMap, "code"));
				if (filePathVo != null) {
					Attachment attr = fileUploadMemberHeadImage(filePathVo.getPath());
					String deleteSql = "DELETE FROM CTP_CUSTOMIZE WHERE USER_ID = '"
							+ MapUtils.getLongValue(memberMap, "id") + "' AND CKEY = 'avatar'";
					int deleteNum = this.jdbcTemplate.update(deleteSql);

					// 清除缓存
					Map map = this.cache.get(MapUtils.getLongValue(memberMap, "id")); // memberID
					if (map != null) {
						CtpCustomize c = (CtpCustomize) map.get(AVATAR_KEY);
						this.cache.remove(c);
					}

					// 添加个人 图标数据
					CtpCustomize customize = new CtpCustomize();
					customize.setIdIfNew();
					customize.setCreateDate(new Date());
					customize.setUserId(MapUtils.getLongValue(memberMap, "id"));
					customize.setCkey(AVATAR_KEY);

					String cValue = "fileId=" + attr.getFileUrl() + "&createDate="
							+ DateFormatUtils.format(attr.getCreatedate(), "yyyy-MM-dd");
					customize.setCvalue(cValue);

					String insertSql = "INSERT INTO CTP_CUSTOMIZE (\"ID\", \"USER_ID\", \"CKEY\", \"CVALUE\", \"CREATE_DATE\") "
							+ "VALUES ('" + customize.getId() + "', '" + customize.getUserId() + "', 'avatar', '"
							+ cValue + "', TO_DATE('" + DateFormatUtils.format(attr.getCreatedate(), "yyyy-MM-dd")
							+ "', 'SYYYY-MM-DD HH24:MI:SS'))";
					int insertNum = this.jdbcTemplate.update(insertSql);
					

					this.cache.update(customize);

			        //修改后的个性化信息中的文件添加到白名单
			        List<CtpCustomize> customizeList=new ArrayList<CtpCustomize>(1);
			        customizeList.add(customize);
			        writePersonalPhotoToFileSecurity(customizeList);
				}
			}
			rMap.put("code", "1000");
			rMap.put("result", "updateMenberHeadImage succ");
			return rMap;
		} catch (Exception e) {
			log.error("=============shkk 个人图标同步错误：" + e.getMessage());
			e.printStackTrace();
			rMap.put("code", "1001");
			rMap.put("result", "updateMenberHeadImage error:" + e.getMessage());
		}
		return rMap;
	}

	/**
	 * 获取文件夹下 所有文件
	 * 
	 * @param filepath
	 */
	public Map<String, FilePathVo> readfile() {
		try {
			Map<String, FilePathVo> map = Maps.newHashMap();
			File file = new File(filepath);
			if (!file.isDirectory()) {
			} else if (file.isDirectory()) {
				String[] filelist = file.list();
				for (int i = 0; i < filelist.length; i++) {
					File readfile = new File(filepath + "/" + filelist[i]);
					String str = filelist[i];
					if (!readfile.isDirectory()) {
						// 加VO 用于获取最新时间的图像
						String key = str.substring(0, str.indexOf("."));
						if (CollectionUtils.isEmpty(map)) {
							FilePathVo filePathVo = new FilePathVo();
							filePathVo.setKey(key);
							filePathVo.setPath(str);
							filePathVo.setTime(readfile.lastModified());
							map.put(key, filePathVo);
						} else {
							FilePathVo fiPathVo = (FilePathVo) MapUtils.getObject(map, key);
							if (null == fiPathVo) {
								FilePathVo filePathVo = new FilePathVo();
								filePathVo.setKey(key);
								filePathVo.setPath(str);
								filePathVo.setTime(readfile.lastModified());
								map.put(key, filePathVo);
							} else if (readfile.lastModified() >= fiPathVo.getTime()) {
								fiPathVo.setPath(str);
								fiPathVo.setTime(readfile.lastModified());
							}
						}
					}
				}
				return map;
			}
		} catch (Exception e) {
			System.out.println("readfile()   Exception:" + e.getMessage());
		}
		return null;
	}

	@Override
	public boolean beforeGrabData() {
		log.info("========shkk 自动修改个人图标任务开始=============");
		updateMenberHeadImage();
		return false;
	}

	@Override
	public boolean grabData() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean addData() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean updateData() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean deleteData() {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * 缓存类
	 * 
	 * @author Administrator
	 *
	 */
	class CustomizeCache {
		private CacheMap<Long, ConcurrentHashMap<String, CtpCustomize>> originCache;

		public CustomizeCache() {
			CacheAccessable factory = CacheFactory.getInstance(CustomizeManager.class);
			this.originCache = factory.createMap("cache");
		}

		public void update(Collection<CtpCustomize> customizes) {
			if (customizes == null)
				return;
			for (CtpCustomize c : customizes)
				update(c);
		}

		public void update(CtpCustomize c) {
			if (c == null)
				return;
			ConcurrentHashMap cacheEntry = (ConcurrentHashMap) this.originCache.get(c.getUserId());
			if (cacheEntry == null) {
				cacheEntry = new ConcurrentHashMap();
				cacheEntry.put(c.getCkey(), c);
				this.originCache.put(c.getUserId(), cacheEntry);
			} else {
				cacheEntry.put(c.getCkey(), c);
				this.originCache.notifyUpdate(c.getUserId(), c.getCkey(), CacheNotification.Action.Put, c);
			}
		}

		public Map<String, CtpCustomize> get(Long memberId) {
			return (Map) this.originCache.get(memberId);
		}

		public List<CtpCustomize> map2List(Map<String, CtpCustomize> map) {
			if (map == null) {
				return null;
			}
			List result = new ArrayList();
			for (CtpCustomize c : map.values()) {
				result.add(c);
			}
			return result;
		}

		public void remove(CtpCustomize c) {
			if (c == null) {
				return;
			}
			Long userId = c.getUserId();

			Map map = (Map) this.originCache.get(userId);
			if (map != null) {
				map.remove(c.getCkey());
			}
			this.originCache.notifyUpdate(userId);
		}

		public void removeAll(Collection<CtpCustomize> customizes) {
			if (customizes == null)
				return;
			for (CtpCustomize c : customizes)
				remove(c);
		}

		public List<CtpCustomize> get(String key) {
			if (key == null) {
				return Collections.emptyList();
			}
			List list = new ArrayList();
			for (ConcurrentHashMap<String, CtpCustomize> map : this.originCache.values()) {
				for (CtpCustomize c : map.values()) {
					if (key.equals(c.getCkey())) {
						list.add(c);
					}
				}
			}
			return list;
		}

		public List<CtpCustomize> get(List<Long> memberIds, String key) {
			if (key == null) {
				return Collections.emptyList();
			}
			List list = new ArrayList();
			for (Long id : memberIds) {
				CtpCustomize value = get(id, key);
				if (value != null) {
					list.add(value);
				}
			}
			return list;
		}

		public CtpCustomize get(Long memberId, String key) {
			if (key == null) {
				return null;
			}
			Map map = get(memberId);
			if (map == null) {
				return null;
			}
			return (CtpCustomize) map.get(key);
		}

		public CtpCustomize find(Long id) {
			if (id == null) {
				return null;
			}
			for (ConcurrentHashMap<String, CtpCustomize> map : this.originCache.values()) {
				for (CtpCustomize c : map.values()) {
					if (id.equals(c.getId())) {
						return c;
					}
				}
			}
			return null;
		}

		public List<CtpCustomize> find(String key, boolean isLike) {
			if (key == null) {
				return Collections.emptyList();
			}
			List list = new ArrayList();
			for (ConcurrentHashMap<String, CtpCustomize> map : this.originCache.values()) {
				for (CtpCustomize c : map.values()) {
					String ckey = c.getCkey();
					if (key.equals(ckey)) {
						list.add(c);
					} else if ((isLike) && (ckey.startsWith(key))) {
						list.add(c);
					}
				}
			}
			return list;
		}
	}
}
